"""
@Author  : 康帅
@Time    : 2021/6/17 10:55
@Function: itertools合并与分割迭代器
"""

from itertools import *


def itertools_chain():
    """
    运用 chain() 函数，可以很轻松的把多个序列合并成一个大的列表
    :return:
    """
    for i in chain([1, 2, 3], ['a', 'b', 'c']):
        print(i, end=' ')
    print()


def itertools_chain_from_iterable():
    """
    有时，甚至输入的那些迭代器也是动态生成的（你可能根本不知道有几个迭代器作为输入），
    这时我们可以用 chain.from_iterable() 来完成和 chain() 相类似的功能
    :return:
    """
    yield [1, 2, 3]
    yield ['a', 'b', 'c']


for i in chain.from_iterable(itertools_chain_from_iterable()):
    print(i, end=' ')
print()


def itertools_zip():
    """
    内置函数 zip() 返回一个迭代器，这个迭代器将同时遍历多个输入迭代器，
    并返回一个由在这些迭代器中得到的元素所组合成的元祖
    :return:
    """
    for i in zip([1, 2, 3], ['a', 'b', 'c']):
        print(i)


def itertools_zip_longest():
    """
    zip() 将会在任意一个输入迭代器被遍历完时停止。
    如果想完整的遍历所有的输入迭代器（即使它们有不同的长度），
    我们可以用 zip_longest() 函数
    :return:
    """
    r1 = range(3)
    r2 = range(2)
    print('zip()提前停止:')
    print(list(zip(r1, r2)))

    r1 = range(3)
    r2 = range(2)
    print('\nzip_longest()处理所有值:')
    print(list(zip_longest(r1, r2)))


def itertools_islice():
    """
    islice() 函数将把输入迭代器的一部分作为其输出的迭代器。
    islice() 和 slice 操作一样，将 start，stop 以及 step 作为输入参数。其中 start 和 step 参数是可选的
    :return:
    """
    print('到5停止:')
    for i in islice(range(100), 5):
        print(i, end=' ')
    print('\n')

    print('从5开始到10结束:')
    for i in islice(range(100), 5, 10):
        print(i, end=' ')
    print('\n')

    print('由10到100，每次以10增加:')
    for i in islice(range(100), 0, 100, 10):
        print(i, end=' ')
    print('\n')


def itertools_tee():
    """
    基于输入，tee() 函数返回多个（默认两个）独立的迭代器
    :return:
    """
    r = islice(count(), 5)
    i1, i2 = tee(r)

    print('i1', list(i1))
    print('i2', list(i2))


def itertools_tee_error():
    """
    这些由 tee() 返回的迭代器会共享它们的输入。
    所以在用 tee() 创建了一些新的迭代器之后，通常原始的那个迭代器不应该再被使用
    :return:
    """
    r = islice(count(), 5)
    i1, i2 = tee(r)

    print('r:', end=' ')
    for i in r:
        print(i, end=' ')
        if i > 1:
            break
    print()

    print('i1:', list(i1))
    print('i2:', list(i2))


if __name__ == '__main__':
    itertools_chain()
    itertools_zip()
    itertools_zip_longest()
    itertools_islice()
    itertools_tee()
    itertools_tee_error()
